home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / zm16src.lzh / ZM.C < prev    next >
C/C++ Source or Header  |  1988-05-19  |  14KB  |  700 lines

  1. /*
  2.  *                ACKNOWLEDGEMENTS
  3.  *
  4.  *    ZMDM was derived from rz/sz for Unix  posted by 
  5.  *    Chuck Forsberg (...!tektronix!reed!omen!caf ). We
  6.  *    thank him for his excellent code, and for giving
  7.  *    us permission to use and distribute his code and
  8.  *    documentation.
  9.  *
  10.  *    Atari St version by:
  11.  *        Jwahar Bammi
  12.  *            usenet: mandrill!bammi@{decvax,sun}.UUCP
  13.  *            csnet:  bammi@mandrill.ces.CWRU.edu
  14.  *            arpa:   bammi@mandrill.ces.CWRU.edu
  15.  *            CompuServe: 71515,155
  16.  */
  17.  
  18. /*
  19.  *   Z M . C
  20.  *    ZMODEM protocol primitives
  21.  *    01-15-87  Chuck Forsberg Omen Technology Inc
  22.  *
  23.  * Entry point Functions:
  24.  *    zsbhdr(type, hdr) send binary header
  25.  *    zshhdr(type, hdr) send hex header
  26.  *    zgethdr(hdr, eflag) receive header - binary or hex
  27.  *    zsdata(buf, len, frameend) send data
  28.  *    zrdata(buf, len) receive data
  29.  *    stohdr(pos) store position data in Txhdr
  30.  *    long rclhdr(hdr) recover position offset from header
  31.  */
  32. #include "config.h"
  33. #include "zmdm.h"
  34. #include "common.h"
  35.  
  36. #ifndef CANFDX
  37. #include "zmodem.h"
  38. #endif
  39.  
  40. #define xsendline(X) sendline(X)
  41.  
  42. static char *frametypes[] = {
  43.     "Carrier Lost",        /* -3 */
  44.     "TIMEOUT",        /* -2 */
  45.     "ERROR",        /* -1 */
  46. #define FTOFFSET 3
  47.     "ZRQINIT",
  48.     "ZRINIT",
  49.     "ZSINIT",
  50.     "ZACK",
  51.     "ZFILE",
  52.     "ZSKIP",
  53.     "ZNAK",
  54.     "ZABORT",
  55.     "ZFIN",
  56.     "ZRPOS",
  57.     "ZDATA",
  58.     "ZEOF",
  59.     "ZFERR",
  60.     "ZCRC",
  61.     "ZCHALLENGE",
  62.     "ZCOMPL",
  63.     "ZCAN",
  64.     "ZFREECNT",
  65.     "ZCOMMAND",
  66.     "ZSTDERR",
  67.     "xxxxx"
  68. #define FRTYPES 22    /* Total number of frame types in this array */
  69.             /*  not including psuedo negative entries */
  70. };
  71.  
  72. /* Send ZMODEM binary header hdr of type type */
  73. zsbhdr(type, hdr)
  74. register int type;
  75. register char *hdr;
  76. {
  77.     register int n;
  78.     register unsigned int crc;
  79.  
  80.     vfile2("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  81.     if (type == ZDATA)
  82.         for (n = Znulls; --n >=0; )
  83.             zsendline(0);
  84.  
  85.     xsendline(ZPAD); xsendline(ZDLE);
  86.  
  87.     if (Txfcs32)
  88.         zsbh32(hdr, type);
  89.     else {
  90.         xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
  91.  
  92.         for (n=4; --n >= 0;) {
  93.             zsendline(*hdr);
  94.             crc = updcrc((0377& *hdr++), crc);
  95.         }
  96.         crc = updcrc(0,updcrc(0,crc));
  97.         zsendline(crc>>8);
  98.         zsendline(crc);
  99.     }
  100.     if (type != ZDATA)
  101.         flush_modem();
  102. }
  103.  
  104.  
  105. /* Send ZMODEM binary header hdr of type type */
  106. zsbh32(hdr, type)
  107. register char *hdr;
  108. register int type;
  109. {
  110.     register int n;
  111.     register unsigned long crc;
  112.  
  113.     xsendline(ZBIN32);  zsendline(type);
  114.     crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
  115.  
  116.     for (n=4; --n >= 0;) {
  117.         zsendline(*hdr);
  118.         crc = UPDC32((0377& *hdr++), crc);
  119.     }
  120.     crc = ~crc;
  121.     for (n=4; --n >= 0;) {
  122.         zsendline((unsigned int)(crc&0xFFFF));  crc >>= 8;
  123.     }
  124. }
  125.  
  126. /* Send ZMODEM HEX header hdr of type type */
  127. zshhdr(type, hdr)
  128. register int type;
  129. register char *hdr;
  130. {
  131.     register int n;
  132.     register unsigned int crc;
  133.  
  134.     vfile2("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  135.     sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX);
  136.     zputhex(type);
  137.  
  138.     crc = updcrc(type, 0);
  139.     for (n=4; --n >= 0;) {
  140.         zputhex(*hdr); crc = updcrc((0377& *hdr++), crc);
  141.     }
  142.     crc = updcrc(0,updcrc(0,crc));
  143.     zputhex(crc>>8); zputhex(crc);
  144.  
  145.     /* Make it printable on remote machine */
  146.     sendline(015); sendline(012);
  147.     /*
  148.      * Uncork the remote in case a fake XOFF has stopped data flow
  149.      */
  150.     if (type != ZFIN)
  151.         sendline(021);
  152.     flush_modem();
  153. }
  154.  
  155. /*
  156.  * Send binary array buf of length length, with ending ZDLE sequence frameend
  157.  */
  158. zsdata(buf, length, frameend)
  159. register char *buf;
  160. register int length, frameend;
  161. {
  162.     register unsigned int crc;
  163.  
  164.     vfile("zsdata: length=%d end=%x", length, frameend);
  165.     if (Txfcs32)
  166.         zsda32(buf, length, frameend);
  167.     else {
  168.         crc = 0;
  169.         for (;--length >= 0;) {
  170.             zsendline(*buf);
  171.             crc = updcrc((0377& *buf++), crc);
  172.         }
  173.         xsendline(ZDLE); xsendline(frameend);
  174.         crc = updcrc(frameend, crc);
  175.  
  176.         crc = updcrc(0,updcrc(0,crc));
  177.         zsendline(crc>>8); zsendline(crc);
  178.     }
  179.     if (frameend == ZCRCW) {
  180.         xsendline(XON);   flush_modem();
  181.     }
  182. }
  183.  
  184. zsda32(buf, length, frameend)
  185. register char *buf;
  186. register int length, frameend;
  187. {
  188.     register unsigned long crc;
  189.  
  190.     crc = 0xFFFFFFFFL;
  191.     for (;--length >= 0;) {
  192.         zsendline(*buf); crc = UPDC32((0377& *buf++), crc);
  193.     }
  194.     xsendline(ZDLE); xsendline(frameend);
  195.     crc = UPDC32(frameend, crc);
  196.  
  197.     crc = ~crc;
  198.     for (length=4; --length >= 0;) {
  199.         zsendline((unsigned int)(crc&0xFFFF));  crc >>= 8;
  200.     }
  201. }
  202.  
  203. /*
  204.  * Receive array buf of max length with ending ZDLE sequence
  205.  *  and CRC.  Returns the ending character or error code.
  206.  */
  207. zrdata(buf, length)
  208. register char *buf;
  209. register int length;
  210. {
  211.     register int c;
  212.     register unsigned int crc;
  213.     register int d;
  214.  
  215.     if (Rxframeind == ZBIN32)
  216.         return zrdat32(buf, length);
  217.  
  218.     crc = Rxcount = 0;
  219.     for (;;) {
  220.         if ((c = zdlread()) & ~0377) {
  221. crcfoo:
  222.             switch (c) {
  223.             case GOTCRCE:
  224.             case GOTCRCG:
  225.             case GOTCRCQ:
  226.             case GOTCRCW:
  227.                 crc = updcrc((d=c)&0377, crc);
  228.                 if ((c = zdlread()) & ~0377)
  229.                     goto crcfoo;
  230.                 crc = updcrc(c, crc);
  231.                 if ((c = zdlread()) & ~0377)
  232.                     goto crcfoo;
  233.                 crc = updcrc(c, crc);
  234.                 if (crc & 0xFFFF) {
  235.                     log2("Bad data CRC %x", crc);
  236.                     return ERROR;
  237.                 }
  238.                 vfile("zrdata: cnt = %d ret = %x", Rxcount, d);
  239.                 return d;
  240.             case GOTCAN:
  241.                 log2("ZMODEM: Sender Canceled");
  242.                 return ZCAN;
  243.             case TIMEOUT:
  244.                 log2("ZMODEM data TIMEOUT");
  245.                 return c;
  246.             default:
  247.                 log2("ZMODEM bad data subpacket ret=%x", c);
  248.                 return c;
  249.             }
  250.         }
  251.         if (--length < 0) {
  252.             log2("ZMODEM data subpacket too long");
  253.             return ERROR;
  254.         }
  255.         ++Rxcount;
  256.         *buf++ = c;
  257.         crc = updcrc(c, crc);
  258.         continue;
  259.     }
  260. }
  261. zrdat32(buf, length)
  262. register char *buf;
  263. register int length;
  264. {
  265.     register int c;
  266.     register unsigned long crc;
  267.     register int d;
  268.  
  269.     crc = 0xFFFFFFFFL;  Rxcount = 0;
  270.     for (;;) {
  271.         if ((c = zdlread()) & ~0377) {
  272. crcfoo:
  273.             switch (c) {
  274.             case GOTCRCE:
  275.             case GOTCRCG:
  276.             case GOTCRCQ:
  277.             case GOTCRCW:
  278.                 crc = UPDC32((d=c)&0377, crc);
  279.                 if ((c = zdlread()) & ~0377)
  280.                     goto crcfoo;
  281.                 crc = UPDC32(c, crc);
  282.                 if ((c = zdlread()) & ~0377)
  283.                     goto crcfoo;
  284.                 crc = UPDC32(c, crc);
  285.                 if ((c = zdlread()) & ~0377)
  286.                     goto crcfoo;
  287.                 crc = UPDC32(c, crc);
  288.                 if ((c = zdlread()) & ~0377)
  289.                     goto crcfoo;
  290.                 crc = UPDC32(c, crc);
  291.                 if (crc != 0xDEBB20E3L) {
  292.                     log2("Bad data CRC");
  293.                     return ERROR;
  294.                 }
  295.                 vfile2("zrdat32: cnt = %ld ret = %x", Rxcount, d);
  296.                 return d;
  297.             case GOTCAN:
  298.                 log2("ZMODEM: Sender Canceled");
  299.                 return ZCAN;
  300.             case TIMEOUT:
  301.                 log2("ZMODEM data TIMEOUT");
  302.                 return c;
  303.             default:
  304.                 log2("ZMODEM bad data subpacket ret");
  305.                 return c;
  306.             }
  307.         }
  308.         if (--length < 0) {
  309.             log2("ZMODEM data subpacket too long");
  310.             return ERROR;
  311.         }
  312.         ++Rxcount;
  313.         *buf++ = c;
  314.         crc = UPDC32(c, crc);
  315.         continue;
  316.     }
  317. }
  318.  
  319.  
  320. /*
  321.  * Read a ZMODEM header to hdr, either binary or hex.
  322.  *  eflag controls local display of non zmodem characters:
  323.  *    0:  no display
  324.  *    1:  display printing characters only
  325.  *    2:  display all non ZMODEM characters
  326.  *  On success, set Zmodem to 1 and return type of header.
  327.  *   Otherwise return negative on error
  328.  */
  329. zgethdr(hdr, eflag)
  330. register char *hdr;
  331. register int eflag;
  332. {
  333.     register int c, n, cancount;
  334.  
  335.     n = Baudrate;    /* Max characters before start of frame */
  336.     cancount = 5;
  337. again:
  338.     Rxframeind = Rxtype = 0;
  339.     switch (c = noxread7()) {
  340.     case RCDO:
  341.     case TIMEOUT:
  342.         goto fifi;
  343.     case CAN:
  344.         if (--cancount <= 0) {
  345.             c = ZCAN; goto fifi;
  346.         }
  347.     /* **** FALL THRU TO **** */
  348.     default:
  349. agn2:
  350.         if ( --n == 0) {
  351.             log2("ZMODEM Garbage count exceeded");
  352.             return(ERROR);
  353.         }
  354.         if (eflag && ((c &= 0177) & 0140))
  355.             bttyout(c);
  356.         else if (eflag > 1)
  357.             bttyout(c);
  358.         if (c != CAN)
  359.             cancount = 5;
  360.         goto again;
  361.     case ZPAD:        /* This is what we want. */
  362.         break;
  363.     }
  364.     cancount = 5;
  365. splat:
  366.     switch (c = noxread7()) {
  367.     case ZPAD:
  368.         goto splat;
  369.     case RCDO:
  370.     case TIMEOUT:
  371.         goto fifi;
  372.     default:
  373.         goto agn2;
  374.     case ZDLE:        /* This is what we want. */
  375.         break;
  376.     }
  377.  
  378.     switch (c = noxread7()) {
  379.     case RCDO:
  380.     case TIMEOUT:
  381.         goto fifi;
  382.     case ZBIN:
  383.         Rxframein